package net.awpspace.relaychat.server;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

/**
 * Server thread
 * 
 * @author Diep Hoang Savvycom JSC
 * 
 */
public class ServerThread extends Thread {

	/**
	 * Unique id include hostname and hostport
	 */
	private String id;

	/**
	 * Friend id
	 */
	private String friendId;

	/**
	 * Communication socket
	 */
	private Socket socket;

	/**
	 * Communication output
	 */
	private OutputStream outputStream;

	/**
	 * Communication input
	 */
	private InputStream inputStream;

	/**
	 * Stop flag
	 */
	private boolean running;

	/**
	 * Callback to notify server
	 */
	private ServerThreadCallback callback;

	public ServerThread(String id, Socket socket, ServerThreadCallback callback) {
		super();
		this.id = id;
		this.socket = socket;
		this.callback = callback;
		try {
			outputStream = socket.getOutputStream();
			inputStream = socket.getInputStream();
		} catch (IOException e) {
		}
	}

	/**
	 * Get unique id
	 * 
	 * @return
	 */
	public String getChatId() {
		return id;
	}

	/**
	 * Set callback for this thread
	 * 
	 * @param callback
	 */
	public void setCallback(ServerThreadCallback callback) {
		this.callback = callback;
	}

	/**
	 * Send message to client
	 * 
	 * @param message
	 */
	public void sendMessage(String message) {
		try {
			outputStream.write(message.getBytes());
		} catch (IOException e) {
		}
	}

	/**
	 * Safety stop thread
	 */
	public void stopRunning() {
		running = false;
		try {
			socket.close();
		} catch (IOException e) {
		}
	}

	@Override
	public void start() {
		running = true;
		super.start();
	}

	@Override
	public void run() {
		while (running) {
			try {
				int msgType = inputStream.read();
				switch (msgType) {
				case 0:
					// CONNECTION_SETUP message

					String friendId = null;

					// get 4 bytes about host name
					int hostFirstByte = inputStream.read();
					int hostSecondByte = inputStream.read();
					int hostThirdByte = inputStream.read();
					int hostFourthByte = inputStream.read();

					// get 2 bytes about host port
					int portMostByte = inputStream.read();
					int portLowestByte = inputStream.read();
					int port = (portMostByte << 8) | (portLowestByte & 0x0f);

					friendId = hostFirstByte + "." + hostSecondByte + "."
							+ hostThirdByte + "." + hostFourthByte + ":" + port;
					System.out.println(id + ": request " + friendId);
					if (callback != null && callback.requestFriend(friendId)) {
						this.friendId = friendId;
						outputStream.write((byte) 1);
					}
					break;
				case 1:
					byte[] buffer = new byte[1024];
					while (inputStream.read(buffer) > 0) {
						if (callback != null) {
							callback.sendMessage(buffer.toString(),
									this.friendId);
						}
					}
					break;
				case 2:
					if (callback != null) {
						callback.requestInterrupt(this);
					}
					break;
				default:
				}
			} catch (IOException e) {
			}
		}
	}
}
